package cn.cttic.base.service.impl;

import cn.cttic.app.api.enums.UserAccountType;
import cn.cttic.base.api.domain.BasePerson;
import cn.cttic.base.api.domain.vo.BaseCompanyVo;
import cn.cttic.base.api.domain.vo.BaseCreatedUserVo;
import cn.cttic.base.api.domain.vo.BasePersonVo;
import cn.cttic.base.service.IBaseCompanyService;
import cn.cttic.common.core.exception.base.BaseException;
import cn.cttic.common.core.service.DictService;
import cn.cttic.common.core.utils.MapstructUtils;
import cn.cttic.common.core.utils.StringUtils;
import cn.cttic.common.satoken.utils.StpUserUtil;
import cn.cttic.order.api.domain.BaseInstallOrder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import cn.cttic.base.api.domain.bo.BaseUserBo;
import cn.cttic.base.api.domain.vo.BaseUserVo;
import cn.cttic.base.api.domain.BaseUser;
import cn.cttic.base.mapper.BaseUserMapper;
import cn.cttic.base.service.IBaseUserService;

import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 账户信息Service业务层处理
 *
 * @author Times.Studio
 * @date 2024-09-17
 */
@RequiredArgsConstructor
@Service
public class BaseUserServiceImpl implements IBaseUserService {

    private final BaseUserMapper baseMapper;

    private final IBaseCompanyService baseCompanyService;

    private final DictService dictService;

    /**
     * 查询账户信息
     *
     * @param id 主键
     * @return 账户信息
     */
    @Override
    public BaseUserVo queryById(String id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 设置账户密码
     *
     * @param id
     * @param password
     * @return
     */
    @Override
    public BaseCreatedUserVo setPassword(String id, String password) {
        BaseUser baseUser = baseMapper.selectById(id);
        String salt = BCrypt.gensalt(12);
        baseUser.setSalt(salt);
        String encryptedPassword = BCrypt.hashpw(password, salt);
        baseUser.setPassword(encryptedPassword);

        int ret = baseMapper.updateById(baseUser);
        if (ret > 0) {
            BaseCreatedUserVo baseCreatedUserVo = new BaseCreatedUserVo();
            baseCreatedUserVo.setUserAccountType(
                baseUser.getType()
            );
            baseCreatedUserVo.setUserName(baseUser.getUserName());
            baseCreatedUserVo.setPassword(password);
            return baseCreatedUserVo;
        } else {
            throw new BaseException("基础管理", "新增销售用户失败");
        }
    }

    /**
     * 查询账户信息
     *
     * @param id 主键
     * @return 账户信息
     */
    @Override
    public BaseCreatedUserVo ressetPassword(String id) {
        BaseUser baseUser = baseMapper.selectById(id);
        String salt = BCrypt.gensalt(12);
        String password = RandomUtil.randomString(8);
        baseUser.setSalt(salt);
        String encryptedPassword = BCrypt.hashpw(password, salt);
        baseUser.setPassword(encryptedPassword);

        int ret = baseMapper.updateById(baseUser);
        if (ret > 0) {
            BaseCreatedUserVo baseCreatedUserVo = new BaseCreatedUserVo();
            baseCreatedUserVo.setUserAccountType(
                baseUser.getType()
            );
            baseCreatedUserVo.setUserName(baseUser.getUserName());
            baseCreatedUserVo.setPassword(password);
            return baseCreatedUserVo;
        } else {
            throw new BaseException("基础管理", "新增销售用户失败");
        }
    }


    /**
     * 查询符合条件的账户信息列表
     *
     * @param bo 查询条件
     * @return 账户信息列表
     */
    @Override
    public List<BaseUserVo> queryList(BaseUserBo bo) {
        LambdaQueryWrapper<BaseUser> lqw = buildQueryWrapper(bo);


        List<BaseUserVo> voList = baseMapper.selectVoList(lqw);
        voList.forEach(bcp -> {
            if (StrUtil.isNotBlank(bcp.getCompanyId())) {
                BaseCompanyVo companyVo = baseCompanyService.queryById(bcp.getCompanyId());
                if (companyVo != null) {
                    bcp.setCompanyName(companyVo.getCompanyName());
                    if (StrUtil.isNotBlank(companyVo.getChannelType())) {
                        bcp.setChannelName(dictService.getDictLabel("dict_channel_type", companyVo.getChannelType()));
                    }
                }
            }
        });

        return voList;
    }

    /**
     * 构建查询调教
     * @param bo 查询请求
     * @return
     */
    private LambdaQueryWrapper<BaseUser> buildQueryWrapper(BaseUserBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BaseUser> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(BaseUser::getCreateTime);
        lqw.eq(StringUtils.isNotBlank(bo.getUserType()), BaseUser::getUserType, bo.getUserType());
        lqw.like(StringUtils.isNotBlank(bo.getUserName()), BaseUser::getUserName, bo.getUserName());
        lqw.like(StringUtils.isNotBlank(bo.getRealName()), BaseUser::getRealName, bo.getRealName());
        lqw.like(StringUtils.isNotBlank(bo.getNickName()), BaseUser::getNickName, bo.getNickName());
        lqw.eq(StringUtils.isNotBlank(bo.getIdCardNo()), BaseUser::getIdCardNo, bo.getIdCardNo());
        lqw.eq(StringUtils.isNotBlank(bo.getEmail()), BaseUser::getEmail, bo.getEmail());
        lqw.eq(StringUtils.isNotBlank(bo.getPhone()), BaseUser::getPhone, bo.getPhone());
        lqw.eq(bo.getGender() != null, BaseUser::getGender, bo.getGender());
        lqw.eq(bo.getBirthday() != null, BaseUser::getBirthday, bo.getBirthday());
        lqw.eq(StringUtils.isNotBlank(bo.getSalt()), BaseUser::getSalt, bo.getSalt());
        lqw.eq(StringUtils.isNotBlank(bo.getPassword()), BaseUser::getPassword, bo.getPassword());
        lqw.eq(bo.getType() != null, BaseUser::getType, bo.getType());
        lqw.eq(bo.getStatus() != null, BaseUser::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getAvatar()), BaseUser::getAvatar, bo.getAvatar());
        lqw.eq(StringUtils.isNotBlank(bo.getPid()), BaseUser::getPid, bo.getPid());
        lqw.eq(bo.getHasChild() != null, BaseUser::getHasChild, bo.getHasChild());
        lqw.eq(bo.getSort() != null, BaseUser::getSort, bo.getSort());
        lqw.eq(StringUtils.isNotBlank(bo.getPersonId()), BaseUser::getPersonId, bo.getPersonId());
        lqw.eq(StringUtils.isNotBlank(bo.getCompanyId()), BaseUser::getCompanyId, bo.getCompanyId());
        lqw.eq(bo.getFirstLogin() != null, BaseUser::getFirstLogin, bo.getFirstLogin());
        lqw.eq(bo.getInitialPassword() != null, BaseUser::getInitialPassword, bo.getInitialPassword());
        return lqw;
    }

    /**
     * 新增账户信息
     *
     * @param bo 账户信息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(BaseUserBo bo) {
        BaseUser add = MapstructUtils.convert(bo, BaseUser.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改账户信息
     *
     * @param bo 账户信息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(BaseUserBo bo) {
        BaseUser update = MapstructUtils.convert(bo, BaseUser.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BaseUser entity){
        //TODO 做一些数据校验,如唯一约束
        List<BaseUser> personList = baseMapper.selectList(
            new LambdaQueryWrapper<BaseUser>().eq(BaseUser::getPhone, entity.getPhone()).eq(BaseUser::getDelFlag, 0)
        );
        if (personList.size() > 0) {
            if (personList.stream().filter( x -> !x.getId().equals(entity.getId())).findAny().isPresent()) {
                throw new BaseException("该手机号已经存在");
            }
        }
    }

    /**
     * 校验并批量删除账户信息信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 启用人员
     *
     * @param id
     * @return
     */
    @Override
    public Boolean enableUser(String id) {
        return baseMapper.update(
            new LambdaUpdateWrapper<BaseUser>()
                .eq(BaseUser::getId, id)
                .set(BaseUser::getStatus, 0)
        ) > 0;
    }

    /**
     * 禁用人员
     *
     * @param id
     * @return
     */
    @Override
    public Boolean disableUser(String id) {
        List<BaseInstallOrder> processingInstallOrderList = baseMapper.getProcessingInstallOrderListByUser(id);
        if (processingInstallOrderList.size() > 0) {
            return false;
        }

       // TODO 踢app用户下线,待与sa-token的多账号体系结合
        try {
            StpUserUtil.logout(id);
        } catch (NotLoginException ignored) {
        }

        return baseMapper.update(
            new LambdaUpdateWrapper<BaseUser>()
                .eq(BaseUser::getId, id)
                .set(BaseUser::getStatus, 1)
        ) > 0;
    }
}
